package com.yiwu.web.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yiwu.common.domain.dto.ChatMessageDTO;
import com.yiwu.common.domain.dto.ChatMessageListDTO;
import com.yiwu.common.domain.dto.ImageConfigDTO;
import com.yiwu.common.domain.dto.UserContactDTO;
import com.yiwu.common.domain.entity.ChatMessage;
import com.yiwu.common.domain.entity.ChatSession;
import com.yiwu.common.domain.entity.ChatSessionUser;
import com.yiwu.common.domain.mapper.ChatMessageMapper;
import com.yiwu.common.domain.mapper.ChatSessionMapper;
import com.yiwu.common.domain.mapper.ChatSessionUserMapper;
import com.yiwu.common.enums.ResponseCode;
import com.yiwu.common.exception.BusinessException;
import com.yiwu.common.model.vo.chat.ChatMessageListReqVO;
import com.yiwu.netty.util.NettyServerUtil;
import com.yiwu.web.service.ChatMessageService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author 咏鹅
 * @description 针对表【Chat_message】的数据库操作Service实现
 * @createDate 2024-05-29 23:07:17
 */
@Slf4j
@Service
public class ChatMessageServiceImpl implements ChatMessageService {

    @Resource
    private NettyServerUtil nettyServerUtil;

    @Resource
    private ChatMessageMapper chatMessageMapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private ChatSessionUserMapper chatSessionUserMapper;

    @Resource
    private ChatSessionMapper chatSessionMapper;

    @Override
    public void addContact2User(String userId, String contactId) {

    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void sendMessage(ChatMessage chatMessage) {

//        Long contactId = chatMessage.getReceiverId();
//        Long userId = chatMessage.getSenderId();
//
//        // 获取当前的 LocalDateTime
//        LocalDateTime localDateTime = LocalDateTime.now();
//        long time = DateUtil.date(localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()).getTime();
//        String sessionId = nettyServerUtil.generateSessionId(userId, contactId);
//        chatMessage.setSessionId(sessionId);
//        chatMessage.setSendTime(time);
//        Long sendTime = System.currentTimeMillis();
//
//        //建立 session 联系
//        // session 表
//        ChatSession chatSession = new ChatSession();
//        chatSession.setLastMessage(chatMessage.getMessageContent());
//        chatSession.setSessionId(sessionId);
//        chatSession.setLastReceiveTime(sendTime);
//
//
//        // sessionUser
//        ChatSessionUser chatSessionUser = new ChatSessionUser();
//        chatSessionUser.setContactId(contactId);
//        chatSessionUser.setUserId(userId);
//        chatSessionUser.setSessionId(sessionId);
//
//        // 查找所联系用户姓名
//        Users user = new Users();
//        Users contactUser = user.selectById(chatSessionUser.getContactId());
//        chatSessionUser.setContactName(contactUser.getUserName());
//        chatSessionUser.setAvatarUrl(contactUser.getAvatarUrl());
//
//
//        Users userInfo = user.selectById(chatSessionUser.getUserId());
//        ChatSessionUser userChat = new ChatSessionUser();
//        userChat.setSessionId(sessionId);
//        userChat.setUserId(contactId);
//        userChat.setContactId(userId);
//        userChat.setContactName(userInfo.getUserName());
//        userChat.setAvatarUrl(userInfo.getAvatarUrl());
//        // 存储
//        try {
//            boolean existence = userChat.existence(userId, contactId);
//            if (!existence) {
//                chatSessionUser.insert();
//            }
//            existence = userChat.existence(contactId, userId);
//            if (!existence) {
//                userChat.insert();
//            }
//            chatSession.insertOrUpdate();
//            nettyServerUtil.send2User(contactId, chatMessage);
//        } catch (Exception e) {
//            log.warn("{}:cmsImpl sendMessage error", chatMessage.getSenderId());
//            throw new BusinessException(ResponseCode.NO_SAVE);
//        }

    }

    @Override
    public void contact2User(ChatSessionUser chatSessionUser) {
        String sessionId = nettyServerUtil.generateSessionId(chatSessionUser.getUserId(), chatSessionUser.getContactId());
        chatSessionUser.setSessionId(sessionId);
    }

    @Override
    public List<ChatMessageListDTO> getMessageList(ChatMessageListReqVO chatMessageListReqVO, Long userId) {
        Page<ChatMessageListDTO> page = new Page<>(chatMessageListReqVO.getCurrent(), chatMessageListReqVO.getSize());
        Page<ChatMessageListDTO> messageList = chatMessageMapper.getMessageList(page, userId);

        return messageList.getRecords();
    }

    @Override
    public List<ChatMessageDTO> getHistoricalMessageList(String sessionId, Long userId, ChatMessageListReqVO chatMessageListReqVO) {
        Long current = chatMessageListReqVO.getCurrent();
        Long size = chatMessageListReqVO.getSize();
        long end = size * current;
        long start = end - size < 0 ? 0 : end - size;
        String title = sessionId + userId + "msg";
        Set<String> previousMessageSet = null;
        //小于等于100就从redis获取消息，大于的就从数据库获取
        if (end <= 100) {
            previousMessageSet = stringRedisTemplate.opsForZSet().range(title, start, end - 2);
            stringRedisTemplate.opsForZSet().removeRange(title, start, end - 2);
        } else {
            // 从数据库里查历史消息
            Long count = stringRedisTemplate.opsForZSet().zCard(title);
            if (count == null) return new ArrayList<>();
            count -= 1;
            Set<String> msg = stringRedisTemplate.opsForZSet().range(title, count, count);
            stringRedisTemplate.opsForZSet().removeRange(title, 0, count);
            if (msg != null && !msg.isEmpty()) {
                Long sendTime = msg.stream()
                        .map(message -> JSONUtil.toBean(message, ChatMessage.class))
                        .filter(Objects::nonNull).toList().getFirst().getSendTime();
                Page<ChatMessage> page = chatMessageMapper.selectPageMessageList(current, size, sessionId, sendTime);
                List<ChatMessageDTO> data = page.getRecords().stream()
                        .map(res -> {
                            ChatMessageDTO dto = new ChatMessageDTO();
                            BeanUtils.copyProperties(res, dto);
                            dto.setSendTime(res.getSendTime().toString());
                            dto.setFileSize(res.getFileSize().toString());
                            dto.setReceiverId(res.getReceiverId().toString());
                            dto.setSenderId(res.getSenderId().toString());
                            return dto;
                        }).toList();
                try {
                    if (!data.isEmpty()) {
                        List<String> list = data.stream().map(ChatMessageDTO::getMid).collect(Collectors.toList());
                        QueryWrapper<ChatMessage> queryWrapper = new QueryWrapper<>();
                        queryWrapper.in("mid",list);
                        chatMessageMapper.delete(queryWrapper);
                    }
                    return data;
                }catch (Exception e){
                    throw new BusinessException(ResponseCode.MSGTYPE_ERROR.getCode(),e.getMessage());
                }
            }
            return new ArrayList<>();
        }


        if (previousMessageSet != null) {
            return previousMessageSet.stream()
                    .map(message -> JSONUtil.toBean(message, ChatMessageDTO.class))
                    .filter(Objects::nonNull).toList();
        }
        return new ArrayList<>();
    }

    @Override
    public String getSession(Long userId, UserContactDTO userContactDTO) {
        String contactId = userContactDTO.getContactId();
        return nettyServerUtil.generateSessionId(userId, Long.parseLong(contactId));
    }


    @Transactional
    @Override
    public Boolean deleteMessageList(String sessionId, String userId) {
        QueryWrapper<ChatSessionUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("session_id", sessionId);
        chatSessionUserMapper.delete(queryWrapper);
        QueryWrapper<ChatSessionUser> chatSessionUserQueryWrapper = new QueryWrapper<>();
        chatSessionUserQueryWrapper.eq("session_id", sessionId);
        Long count = chatSessionUserMapper.selectCount(chatSessionUserQueryWrapper);
        if (count <= 0) {
            chatSessionMapper.deleteById(sessionId);
            UpdateWrapper<ChatMessage> updateWrapper = new UpdateWrapper<>();
            updateWrapper.set("status", 1);
            updateWrapper.eq("session_id", sessionId);
            chatMessageMapper.update(updateWrapper);
        }
        return true;
    }
}




